package com.hanxiaozhang.threadbase1ndedition.no5juccommonclass;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

/**
 * 〈一句话功能简述〉<br>
 * 〈LongAdder的使用〉
 * <p>
 * 概念：
 * LongAdder是JDK1.8新增的一个原子性操作类
 * <p>
 * 常见方法：
 * add(long x) 增加
 * decrement() -> add(-1L)  自减
 * increment() -> add(1L)  自增
 * sum() 返回值
 * longValue() -> sum() 返回值long
 * intValue() -> (int)sum() 返回值int
 *
 * @author hanxinghua
 * @create 2021/11/11
 * @since 1.0.0
 */
public class No1LongAdder {


    private static AtomicLong COUNT_1 = new AtomicLong(0L);
    private static long COUNT_2 = 0L;
    private static LongAdder COUNT_3 = new LongAdder();

    public static void main(String[] args) throws Exception {

        Thread[] threads = new Thread[1000];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int k = 0; k < 100000; k++) {
                    COUNT_1.incrementAndGet();
                }
            });
        }

        long start = System.currentTimeMillis();
        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }
        long end = System.currentTimeMillis();

        // TimeUnit.SECONDS.sleep(10);

        System.out.println("Atomic: " + COUNT_1.get() + " time " + (end - start));


        Object lock = new Object();

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int k = 0; k < 100000; k++) {
                        synchronized (lock) {
                            COUNT_2++;
                        }
                    }

                }
            });
        }

        start = System.currentTimeMillis();
        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }
        end = System.currentTimeMillis();

        System.out.println("Sync: " + COUNT_2 + " time " + (end - start));


        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(() -> {
                for (int k = 0; k < 100000; k++) {
                    COUNT_3.increment();
                }
            });
        }

        start = System.currentTimeMillis();
        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }
        end = System.currentTimeMillis();

        //TimeUnit.SECONDS.sleep(10);

        System.out.println("LongAdder: " + COUNT_1.longValue() + " time " + (end - start));

    }


}
